1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package nl.toolforge.karma.core.cmd.impl;
20
21
22 import nl.toolforge.karma.core.cmd.Command;
23 import nl.toolforge.karma.core.cmd.CommandDescriptor;
24 import nl.toolforge.karma.core.cmd.CommandException;
25 import nl.toolforge.karma.core.cmd.CommandFactory;
26 import nl.toolforge.karma.core.cmd.CommandLoadException;
27 import nl.toolforge.karma.core.cmd.CommandResponse;
28 import nl.toolforge.karma.core.cmd.event.ErrorEvent;
29 import nl.toolforge.karma.core.cmd.event.ExceptionEvent;
30 import nl.toolforge.karma.core.cmd.event.MessageEvent;
31 import nl.toolforge.karma.core.cmd.event.SimpleMessage;
32 import nl.toolforge.karma.core.cmd.util.DependencyException;
33 import nl.toolforge.karma.core.cmd.util.DependencyHelper;
34 import nl.toolforge.karma.core.cmd.util.DependencyPath;
35 import nl.toolforge.karma.core.cmd.util.DescriptorReader;
36 import nl.toolforge.karma.core.manifest.ManifestException;
37 import nl.toolforge.karma.core.module.Module;
38 import nl.toolforge.karma.core.module.ModuleDigester;
39 import nl.toolforge.karma.core.module.ModuleTypeException;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.tools.ant.BuildException;
43 import org.apache.tools.ant.Project;
44 import org.apache.tools.ant.Target;
45 import org.apache.tools.ant.taskdefs.Copy;
46 import org.apache.tools.ant.taskdefs.Ear;
47 import org.apache.tools.ant.taskdefs.Jar;
48 import org.apache.tools.ant.taskdefs.Mkdir;
49 import org.apache.tools.ant.taskdefs.War;
50 import org.apache.tools.ant.taskdefs.Zip;
51 import org.apache.tools.ant.types.FileSet;
52 import org.apache.tools.ant.types.FilterSet;
53 import org.xml.sax.SAXException;
54
55 import java.io.File;
56 import java.io.IOException;
57 import java.util.Hashtable;
58 import java.util.Iterator;
59 import java.util.Map;
60 import java.util.Set;
61 import java.util.regex.Matcher;
62 import java.util.regex.Pattern;
63
64 /***
65 * @author D.A. Smedes
66 * @author W.H. Schraal
67 *
68 * @version $Id: PackageModule.java,v 1.51 2004/11/16 22:28:02 hippe Exp $
69 */
70 public class PackageModule extends AbstractBuildCommand {
71
72 public static final String COMMAND_NAME = "package-module";
73
74 private static final Log logger = LogFactory.getLog(PackageModule.class);
75
76 private CommandResponse commandResponse = new CommandResponse();
77
78 public PackageModule(CommandDescriptor descriptor) {
79 super(descriptor);
80 }
81
82 public void execute() throws CommandException {
83
84 super.execute();
85
86 DependencyHelper helper = new DependencyHelper(getCurrentManifest());
87
88 try {
89 boolean dependenciesChecked = false;
90 while (!dependenciesChecked) {
91 try {
92 helper.getModuleDependencies(getCurrentModule(), false, true);
93 dependenciesChecked = true;
94 } catch (DependencyException de) {
95 if (de.getErrorCode().equals(DependencyException.DEPENDENCY_NOT_FOUND)) {
96
97
98
99 String dep = (String) de.getMessageArguments()[0];
100 try {
101 Module module = getCurrentManifest().getModule(dep);
102 Command command = null;
103 try {
104
105 getCommandResponse().addEvent(
106 new MessageEvent(this, new SimpleMessage("Module `{0}` is needed, but is not packaged yet. Doing that now.", new Object[]{module.getName()})));
107
108 String commandLineString;
109 if (!getCommandLine().hasOption("n")) {
110 commandLineString = "pam -m " + module.getName();
111 } else {
112 commandLineString = "pam -n -m " + module.getName();
113 }
114 logger.debug("Going to: "+commandLineString);
115 command = CommandFactory.getInstance().getCommand(commandLineString);
116 command.setContext(getContext());
117 command.registerCommandResponseListener(getResponseListener());
118 command.execute();
119
120
121 } catch (CommandLoadException e) {
122 throw new CommandException(e.getErrorCode(), e.getMessageArguments());
123 } finally {
124 if ( command != null ) {
125 command.deregisterCommandResponseListener(getResponseListener());
126 }
127 }
128 } catch (ManifestException me) {
129
130 throw de;
131 }
132 } else {
133
134 throw de;
135 }
136 }
137 }
138 } catch (DependencyException e) {
139 logger.error(e);
140 throw new CommandException(e.getErrorCode(), e.getMessageArguments());
141 } catch (ModuleTypeException e) {
142 logger.error(e);
143 throw new CommandException(e.getErrorCode(), e.getMessageArguments());
144 }
145
146 try {
147
148 if ( ! getCommandLine().hasOption("n") ) {
149
150 logger.info("Going to run the unit tests before packaging.");
151
152 Command command = null;
153 try {
154
155 String commandLineString = "tm -n -m " + module.getName();
156
157 command = CommandFactory.getInstance().getCommand(commandLineString);
158 command.setContext(getContext());
159 command.registerCommandResponseListener(getResponseListener());
160 command.execute();
161
162 } catch (CommandException ce) {
163 if (ce.getErrorCode().equals(CommandException.TEST_FAILED)) {
164 commandResponse.addEvent(new ErrorEvent(this, ce.getErrorCode(), ce.getMessageArguments()));
165 throw new CommandException(ce, CommandException.PACKAGE_FAILED, new Object[]{module.getName()});
166 } else if (ce.getErrorCode().equals(CommandException.NO_TEST_DIR)) {
167
168 commandResponse.addEvent(new ErrorEvent(this, ce.getErrorCode(), ce.getMessageArguments()));
169 } else {
170 commandResponse.addEvent(new ErrorEvent(this, ce.getErrorCode(), ce.getMessageArguments()));
171 }
172 } catch (CommandLoadException e) {
173 throw new CommandException(e.getErrorCode(), e.getMessageArguments());
174 } finally {
175 if ( command != null ) {
176 command.deregisterCommandResponseListener(getResponseListener());
177 }
178 }
179
180 } else {
181 logger.info("User has explicitly disabled running the unit tests.");
182 Command command = null;
183 try {
184
185 String commandLineString = "bm -n -m " + module.getName();
186 logger.debug("Going to: "+commandLineString);
187 command = CommandFactory.getInstance().getCommand(commandLineString);
188 command.setContext(getContext());
189 command.registerCommandResponseListener(getResponseListener());
190 command.execute();
191 } catch (CommandException ce) {
192 if (ce.getErrorCode().equals(CommandException.DEPENDENCY_DOES_NOT_EXIST) ||
193 ce.getErrorCode().equals(CommandException.BUILD_FAILED) ||
194 ce.getErrorCode().equals(DependencyException.DEPENDENCY_NOT_FOUND) ) {
195 commandResponse.addEvent(new ErrorEvent(this, ce.getErrorCode(), ce.getMessageArguments()));
196 throw new CommandException(ce, CommandException.PACKAGE_FAILED, new Object[]{module.getName()});
197 } else if (ce.getErrorCode().equals(CommandException.NO_SRC_DIR)) {
198
199 } else {
200 commandResponse.addEvent(new ErrorEvent(this, ce.getErrorCode(), ce.getMessageArguments()));
201 }
202 } catch (CommandLoadException e) {
203 throw new CommandException(e.getErrorCode(), e.getMessageArguments());
204 } finally {
205 if ( command != null ) {
206 command.deregisterCommandResponseListener(getResponseListener());
207 }
208 }
209 }
210
211
212 String archiveName = helper.resolveArchiveName(getCurrentModule());
213 File packageName = new File(getBuildEnvironment().getModuleBuildRootDirectory(), archiveName);
214
215 if (getCurrentModule().getType().equals(Module.JAVA_WEB_APPLICATION)) {
216 packageWar(packageName);
217 } else if (getCurrentModule().getType().equals(Module.JAVA_ENTERPRISE_APPLICATION)) {
218 packageEar(packageName);
219 } else if (getCurrentModule().getType().equals(Module.JAVA_SOURCE_MODULE)) {
220 packageJar(packageName);
221 } else if (getCurrentModule().getType().equals(Module.OTHER_MODULE)) {
222 packageOther(packageName);
223 } else {
224 throw new CommandException(CommandException.PACKAGE_FAILED_WRONG_MODULE_TYPE, new Object[]{getCurrentModule()});
225 }
226
227 SimpleMessage message =
228 new SimpleMessage(
229 getFrontendMessages().getString("message.MODULE_PACKAGED"),
230 new Object[] {getCurrentModule().getName(), archiveName});
231 commandResponse.addEvent(new MessageEvent(this, message));
232
233 } catch (DependencyException d) {
234 throw new CommandException(d.getErrorCode(), d.getMessageArguments());
235 } catch (ModuleTypeException d) {
236 throw new CommandException(d.getErrorCode(), d.getMessageArguments());
237 }
238 }
239
240 private void packageOther(File packageName) throws CommandException {/package-summary.html">g> void packageOther(File packageName) throws CommandException {
241 Project project = getProjectInstance();
242
243 Target target = new Target();
244 target.setName("run");
245 target.setProject(project);
246
247 project.addTarget(target);
248
249 executeDelete(getBuildEnvironment().getModuleBuildDirectory(), "*.zip");
250
251 Copy copy = null;
252 FileSet fileSet = null;
253
254
255 if (getCurrentModule().getBaseDir().exists()) {
256 copy = (Copy) project.createTask("copy");
257 copy.setProject(getProjectInstance());
258 copy.setTodir(getBuildEnvironment().getModulePackageDirectory());
259 copy.setOverwrite(true);
260 copy.setIncludeEmptyDirs(false);
261
262 fileSet = new FileSet();
263 fileSet.setDir(getCurrentModule().getBaseDir());
264 fileSet.setIncludes("**/*");
265 fileSet.setExcludes("history.xml,module-descriptor.xml,.*");
266
267 copy.addFileset(fileSet);
268 target.addTask(copy);
269 } else {
270 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("No resources available.")));
271 }
272 project.executeTarget("run");
273
274 if (getBuildEnvironment().getModulePackageDirectory().exists()) {
275 Target target2 = new Target();
276 target2.setName("zip");
277 target2.setProject(project);
278
279 project.addTarget(target2);
280 Zip zip = (Zip) project.createTask("zip");
281 zip.setProject(getProjectInstance());
282 zip.setDestFile(packageName);
283 zip.setBasedir(getBuildEnvironment().getModulePackageDirectory());
284 target2.addTask(zip);
285 project.executeTarget("zip");
286 } else {
287 throw new CommandException(CommandException.PACKAGE_FAILED_NOTHING_TO_PACKAGE, new Object[]{getCurrentModule()});
288 }
289 }
290
291 private void packageJar(File packageName) throws CommandException {/package-summary.html">g> void packageJar(File packageName) throws CommandException {
292
293 try {
294 Project project = getProjectInstance();
295
296 Target target = new Target();
297 target.setName("run");
298 target.setProject(project);
299
300 project.addTarget(target);
301
302 executeDelete(getBuildEnvironment().getModuleBuildDirectory(), "*.jar");
303
304 Copy copy = null;
305 FileSet fileSet = null;
306
307
308 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Copying the resources...")));
309 if (new File(getCurrentModule().getBaseDir(), "src/resources").exists()) {
310 copy = (Copy) project.createTask("copy");
311 copy.setProject(getProjectInstance());
312 copy.setTodir(getBuildEnvironment().getModulePackageDirectory());
313 copy.setOverwrite(true);
314 copy.setIncludeEmptyDirs(false);
315
316 fileSet = new FileSet();
317 fileSet.setDir(new File(getCurrentModule().getBaseDir(), "src/resources"));
318 fileSet.setIncludes("**/*");
319
320 copy.addFileset(fileSet);
321 target.addTask(copy);
322 } else {
323 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("No resources available.")));
324 }
325
326
327 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Copying the META-INF...")));
328 if (new File(getCurrentModule().getBaseDir(), "src/META-INF").exists()) {
329 copy = (Copy) project.createTask("copy");
330 copy.setProject(getProjectInstance());
331 copy.setTodir(getBuildEnvironment().getModulePackageDirectory());
332 copy.setOverwrite(true);
333 copy.setIncludeEmptyDirs(false);
334
335 fileSet = new FileSet();
336 fileSet.setDir(new File(getCurrentModule().getBaseDir(), "src"));
337 fileSet.setIncludes("META-INF/**");
338
339 copy.addFileset(fileSet);
340 target.addTask(copy);
341 } else {
342 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("No META-INF available.")));
343 }
344
345
346 if (getCompileDirectory().exists()) {
347 copy = (Copy) project.createTask("copy");
348 copy.setProject(getProjectInstance());
349 copy.setTodir(getBuildEnvironment().getModulePackageDirectory());
350 copy.setOverwrite(true);
351 copy.setIncludeEmptyDirs(false);
352
353 fileSet = new FileSet();
354 fileSet.setDir(getCompileDirectory());
355 fileSet.setIncludes("**/*.class");
356
357 copy.addFileset(fileSet);
358 target.addTask(copy);
359 }
360 project.executeTarget("run");
361
362 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Packaging...")));
363 Target target2 = new Target();
364 target2.setName("jar");
365 target2.setProject(project);
366
367 project.addTarget(target2);
368 if (getBuildEnvironment().getModulePackageDirectory().exists()) {
369 Jar jar = (Jar) project.createTask("jar");
370 jar.setProject(getProjectInstance());
371 jar.setDestFile(packageName);
372 jar.setBasedir(getBuildEnvironment().getModulePackageDirectory());
373 jar.setExcludes("*.jar");
374 target2.addTask(jar);
375
376 project.executeTarget("jar");
377 } else {
378 throw new CommandException(CommandException.PACKAGE_FAILED, new Object[] {getCurrentModule().getName()});
379 }
380 } catch (BuildException e) {
381 e.printStackTrace();
382 if (logger.isDebugEnabled()) {
383 commandResponse.addEvent(new ExceptionEvent(this, e));
384 }
385 throw new CommandException(e, CommandException.PACKAGE_FAILED, new Object[] {getCurrentModule().getName()});
386 } catch (ModuleTypeException e) {
387 throw new CommandException(e.getErrorCode(), e.getMessageArguments());
388 }
389
390 }
391
392 private void packageWar(File packageName) throws CommandException {/package-summary.html">g> void packageWar(File packageName) throws CommandException {
393
394 Project project = getProjectInstance();
395
396 Target target = new Target();
397 target.setName("run");
398 target.setProject(project);
399
400 project.addTarget(target);
401
402 DependencyHelper helper = new DependencyHelper(getCurrentManifest());
403
404 try {
405 executeDelete(getBuildEnvironment().getModuleBuildDirectory(), "*.war");
406
407
408
409 Copy copy;
410 File webdir = new File(new File(getCurrentModule().getBaseDir(), "src"), "web");
411 FileSet fileSet;
412
413
414 Mkdir mkdir = (Mkdir) project.createTask("mkdir");
415 mkdir.setDir(getBuildEnvironment().getModulePackageDirectory());
416 target.addTask(mkdir);
417
418
419
420 if (webdir.exists()) {
421 copy = (Copy) project.createTask("copy");
422 copy.setProject(getProjectInstance());
423 copy.setTodir(getBuildEnvironment().getModulePackageDirectory());
424 copy.setOverwrite(true);
425 copy.setIncludeEmptyDirs(false);
426
427 fileSet = new FileSet();
428 fileSet.setDir(webdir);
429 fileSet.setIncludes("**");
430 fileSet.setExcludes("WEB-INF/web.xml");
431
432 copy.addFileset(fileSet);
433 target.addTask(copy);
434 }
435
436
437
438
439 Set deps = helper.getAllDependencies(getCurrentModule(),false, true);
440 if (!deps.isEmpty()) {
441
442 copy = (Copy) project.createTask("copy");
443 copy.setProject(getProjectInstance());
444 copy.setTodir(new File(getBuildEnvironment().getModulePackageDirectory(), "WEB-INF/lib"));
445 copy.setFlatten(true);
446 copy.setIncludeEmptyDirs(false);
447
448
449
450 Iterator it = deps.iterator();
451 while (it.hasNext()) {
452 DependencyPath path = (DependencyPath) it.next();
453 fileSet = new FileSet();
454 fileSet.setFile(path.getFullPath());
455 copy.addFileset(fileSet);
456 }
457
458 target.addTask(copy);
459 }
460
461
462
463 War war = (War) project.createTask("war");
464 war.setProject(getProjectInstance());
465 war.setDestFile(packageName);
466 war.setBasedir(getBuildEnvironment().getModulePackageDirectory());
467 war.setWebxml(new File(getCurrentModule().getBaseDir(), "src/web/WEB-INF/web.xml".replace('/', File.separatorChar)));
468
469 target.addTask(war);
470 project.executeTarget("run");
471
472 } catch (BuildException e) {
473 e.printStackTrace();
474 if (logger.isDebugEnabled()) {
475 commandResponse.addEvent(new ExceptionEvent(this, e));
476 }
477 throw new CommandException(e, CommandException.PACKAGE_FAILED, new Object[] {getCurrentModule().getName()});
478 } catch (DependencyException d) {
479 d.printStackTrace();
480 throw new CommandException(d.getErrorCode(), d.getMessageArguments());
481 } catch (ModuleTypeException d) {
482 d.printStackTrace();
483 throw new CommandException(d.getErrorCode(), d.getMessageArguments());
484 }
485
486 }
487
488 private void packageEar(File packageName) throws CommandException {/package-summary.html">g> void packageEar(File packageName) throws CommandException {
489
490 Project project = getProjectInstance();
491
492 Target target = new Target();
493 target.setName("run");
494 target.setProject(project);
495
496 project.addTarget(target);
497
498 DependencyHelper helper = new DependencyHelper(getCurrentManifest());
499
500 try {
501
502
503
504
505 DescriptorReader reader = new DescriptorReader(DescriptorReader.APPLICATION_XML);
506 try {
507 reader.parse(new File(getCurrentModule().getBaseDir(), "src/META-INF"));
508 } catch (IOException e) {
509 throw new CommandException(CommandException.PACKAGE_FAILED_NO_APPLICATION_XML, new Object[]{module.getName()});
510 } catch (SAXException e) {
511 throw new CommandException(CommandException.PACKAGE_FAILED_INVALID_APPLICATION_XML, new Object[]{module.getName()});
512 }
513
514
515
516
517 Map map = new Hashtable();
518 for (Iterator it = reader.getModuleNames().iterator(); it.hasNext(); ) {
519 String moduleName = ((StringBuffer) it.next()).toString();
520 Pattern p = Pattern.compile("@("+ModuleDigester.NAME_PATTERN_STRING+")@");
521 Matcher m = p.matcher(moduleName);
522
523 if (m.matches()) {
524 moduleName = m.group(1);
525 Module mod;
526 try {
527 mod = getCurrentManifest().getModule(moduleName);
528 } catch (ManifestException me) {
529 throw new DependencyException(DependencyException.EAR_DEPENDENCY_NOT_FOUND, new Object[]{moduleName});
530 }
531
532 map.put(moduleName, helper.resolveArchiveName(mod));
533
534 if (!helper.hasModuleDependency(getCurrentModule(), mod, true)) {
535 throw new DependencyException(DependencyException.EAR_DEPENDENCY_NOT_DEFINED, new Object[]{moduleName});
536 }
537 } else {
538
539 }
540 }
541
542 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Deleting previous ear file.")));
543 executeDelete(getBuildEnvironment().getModuleBuildDirectory(), "*.ear");
544
545 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Copying META-INF dir.")));
546 Copy copyMetaInf = (Copy) project.createTask("copy");
547 copyMetaInf.setProject(getProjectInstance());
548 copyMetaInf.setTodir(getBuildEnvironment().getModulePackageDirectory());
549 copyMetaInf.setOverwrite(true);
550 copyMetaInf.setIncludeEmptyDirs(false);
551
552 FileSet fileSet = new FileSet();
553 fileSet.setDir(new File(getCurrentModule().getBaseDir(), "src"));
554 fileSet.setIncludes("META-INF/**");
555
556
557
558 helper.createModuleDependenciesFilter(module);
559 FilterSet filterSet = copyMetaInf.createFilterSet();
560 filterSet.setFiltersfile(new File(getBuildEnvironment().getModuleBuildDirectory(), DependencyHelper.MODULE_DEPENDENCIES_PROPERTIES));
561
562 copyMetaInf.addFileset(fileSet);
563 target.addTask(copyMetaInf);
564
565
566 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Copying module dependencies")));
567 Set moduleDeps = helper.getModuleDependencies(getCurrentModule(), false, true);
568 if (!moduleDeps.isEmpty()) {
569 Copy copy = (Copy) project.createTask("copy");
570 copy.setProject(getProjectInstance());
571 copy.setTodir(getBuildEnvironment().getModulePackageDirectory());
572 copy.setFlatten(true);
573 copy.setIncludeEmptyDirs(false);
574
575 Iterator it = moduleDeps.iterator();
576 while (it.hasNext()) {
577 DependencyPath path = (DependencyPath) it.next();
578 fileSet = new FileSet();
579 fileSet.setFile(path.getFullPath());
580 copy.addFileset(fileSet);
581 }
582 target.addTask(copy);
583 } else {
584 logger.info("No module dependencies to package.");
585 }
586
587
588 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Copying jar dependencies")));
589 Set jarDeps = helper.getJarDependencies(getCurrentModule(), true);
590 if (!jarDeps.isEmpty()) {
591 Copy copy = (Copy) project.createTask("copy");
592 copy.setProject(getProjectInstance());
593 copy.setTodir(new File(getBuildEnvironment().getModulePackageDirectory(), "lib"));
594 copy.setFlatten(true);
595 copy.setIncludeEmptyDirs(false);
596
597 Iterator it = jarDeps.iterator();
598 while (it.hasNext()) {
599 DependencyPath path = (DependencyPath) it.next();
600 fileSet = new FileSet();
601 fileSet.setFile(path.getFullPath());
602 copy.addFileset(fileSet);
603 }
604 target.addTask(copy);
605 } else {
606 logger.info("No jar dependencies to package.");
607 }
608 project.executeTarget("run");
609
610 commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("Creating ear")));
611 Target target2 = new Target();
612 target2.setName("ear");
613 target2.setProject(project);
614
615 project.addTarget(target2);
616
617 Ear ear = (Ear) project.createTask("ear");
618 ear.setProject(getProjectInstance());
619 ear.setDestFile(packageName);
620 ear.setBasedir(getBuildEnvironment().getModulePackageDirectory());
621 ear.setExcludes("META-INF/application.xml");
622 ear.setAppxml(new File(getBuildEnvironment().getModulePackageDirectory(), "META-INF/application.xml".replace('/', File.separatorChar)));
623
624 target2.addTask(ear);
625 project.executeTarget("ear");
626 } catch (BuildException e) {
627 e.printStackTrace();
628 if (logger.isDebugEnabled()) {
629 commandResponse.addEvent(new ExceptionEvent(this, e));
630 }
631 throw new CommandException(e, CommandException.PACKAGE_FAILED, new Object[] {getCurrentModule().getName()});
632 } catch (DependencyException d) {
633 throw new CommandException(d.getErrorCode(), d.getMessageArguments());
634 } catch (ModuleTypeException d) {
635 throw new CommandException(d.getErrorCode(), d.getMessageArguments());
636 }
637
638 }
639
640 /***
641 * Gets the commands' response object.
642 *
643 * @return The commands' response object.
644 */
645 public CommandResponse getCommandResponse() {
646 return commandResponse;
647 }
648
649 }